﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace MagicArena.framework.physics
{
    public abstract class APhysicsEngine : IUpdateable
    {

        private List<ACollider> _Colliders = new List<ACollider>(10);
        protected List<ACollider> Colliders
        {
            get
            {
                return _Colliders;
            }
        }

        public void AddCollider(ACollider col)
        {
            if(ColliderSupportCheck(col))
                _Colliders.Add(col);
        }
        public void RemoveCollider(ACollider col)
        {
            if (ColliderSupportCheck(col))
                _Colliders.Remove(col);
        }
        public void ClearColliders()
        {
            _Colliders.Clear();
        }

        /// <summary>
        /// Checks if the given ACollider type is supported bt this physics engine
        /// </summary>
        /// <param name="col">Collider to check support for</param>
        /// <returns>true if supported, false if not</returns>
        protected abstract bool ColliderSupportCheck(ACollider col);

        #region IUpdatable methods
        #region Enabled
        private bool _Enabled = false;
        public bool Enabled
        {
            get { return _Enabled; }
            set
            {
                if (_Enabled != value)
                {
                    _Enabled = value;
                    OnEnabledChanged(new EnabledEventArgs(value));
                }
                _Enabled = value;
            }
        }
        public event EventHandler<EventArgs> EnabledChanged;
        public class EnabledEventArgs : EventArgs
        {
            public bool NewState
            {
                get;
                private set;
            }
            public EnabledEventArgs(bool state)
            {
                NewState = state;
            }
        }
        protected virtual void OnEnabledChanged(EventArgs e)
        {
            if (EnabledChanged != null) EnabledChanged(this, e);
        }
        #endregion

        #region Update
        public abstract void Update(GameTime gameTime);

        private int _UpdateOrder = int.MaxValue / 2;
        public int UpdateOrder
        {
            //TODO figure out a logical update order
            get { return _UpdateOrder; }
            protected set
            {
                if (_UpdateOrder != value)
                {
                    _UpdateOrder = value;
                    OnUpdateOrderChanged(new UpdateOrderEventArgs(value));
                }
                _UpdateOrder = value;
            }
        }

        public event EventHandler<EventArgs> UpdateOrderChanged;
        protected virtual void OnUpdateOrderChanged(UpdateOrderEventArgs e)
        {
            if (UpdateOrderChanged != null) UpdateOrderChanged(this, e);
        }
        public class UpdateOrderEventArgs : EventArgs
        {
            public int NewValue
            {
                get;
                private set;
            }
            public UpdateOrderEventArgs(int val)
            {
                NewValue = val;
            }
        }
        #endregion
        #endregion
    }
}
